﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Utility.Data.DbClient;

namespace Quick.CodeGenerator.Data
{
    public class MySql:IDataBase
    {
        Utility.DBUtility.DatabaseOperate.DbHelperMySql m_MySql = new Utility.DBUtility.DatabaseOperate.DbHelperMySql();
        /// <summary>
        /// 表字段名称
        /// </summary>
        public override string TableName { get { return "TABLE_NAME"; } }
        /// <summary>
        /// 根据关键字,获取指定的表名
        /// </summary>
        /// <param name="keyWords"></param>
        /// <returns></returns>
        public override List<Model.TableInfo> GetTableListInfo(string keyWords)
        {
            string sql = @"SELECT
	                TABLE_NAME TABLENAME,
                    CASE TABLE_TYPE
	                    WHEN 'BASE TABLE'
                    THEN 'TABLE'
	                    ELSE TABLE_TYPE
	                END TABLETYPE
                FROM
	                INFORMATION_SCHEMA.TABLES
                WHERE
	                TABLE_SCHEMA = DATABASE() ";
            string sqlWhere = CreateTableInfoSqlWhere(keyWords);
            if (!string.IsNullOrEmpty(sqlWhere))
            {
                sql += $" AND {sqlWhere} ";
            }
            return m_MySql.Query<Model.TableInfo>(sql, this.m_ConnectonString);
        }
        /// <summary>
        /// 获取指定表名的列数据
        /// </summary>
        /// <param name="tableName"></param>
        /// <returns></returns>
        public override List<Model.ColumnInfo> GetColumnInfoList(string tableName)
        {
            string sql = @" SELECT
                                COLUMN_NAME,
                                DATA_TYPE,
                                CASE WHEN ISNULL(CHARACTER_MAXIMUM_LENGTH) THEN NUMERIC_PRECISION ELSE CHARACTER_MAXIMUM_LENGTH END DATA_LENGTH,
                                NUMERIC_PRECISION DATA_PRECISION,
                                NUMERIC_SCALE DATA_SCALE,
                                CASE IS_NULLABLE WHEN 'YES' THEN 'Y' ELSE 'N' END NULLABLE,
                                COLUMN_DEFAULT DATA_DEFAULT,
                                COLUMN_COMMENT COMMENTS,
                                TABLE_NAME,
                                CASE COLUMN_KEY WHEN 'PRI' THEN 'P' ELSE '' END CONSTRAINT_TYPE,
                                TABLE_SCHEMA OBJECT_TYPE
                            FROM
                                INFORMATION_SCHEMA.COLUMNS
                            WHERE
                                TABLE_NAME = :TABLE_NAME
                            AND TABLE_SCHEMA = DATABASE () ";
            DBParameter[] parameters = { new DBParameter(":TABLE_NAME", DBType.Oracle_Varchar2, 50) };
            parameters[0].Value = tableName;
            return TransfromDbType2DbParameterType(m_MySql.Query<Model.ColumnInfo>(sql, this.m_ConnectonString, parameters));
        }

        /// <summary>
        /// 根据查询的数据类型转换成OracleDbType数据类型
        /// </summary>
        /// <param name="type">数据类型</param>
        /// <param name="isDecimal">是否是小数</param>
        /// <param name="length">数据长度</param>
        /// <returns></returns>
        public override string TransfromDbType2DbParameterType(string type, string decimalStr, string length)
        {
            bool isDecimal = !string.IsNullOrEmpty(decimalStr) && int.Parse(decimalStr) > 0;
            if (string.IsNullOrEmpty(type))
            {
                return string.Empty;
            }

            if (string.Equals(type, "INTEGER", StringComparison.OrdinalIgnoreCase)
                ||  string.Equals(type, "INT", StringComparison.OrdinalIgnoreCase)
                || (string.Equals(type, "NUMBER", StringComparison.OrdinalIgnoreCase) && !isDecimal))
            {
                return "DBType.MySql_Int32, Length = " + length;
            }
            else if (string.Equals(type, "bigint", StringComparison.OrdinalIgnoreCase))
            {
                return "DBType.MySql_Int64, Length = " + length;
            }
            else if (string.Equals(type, "DECIMAL", StringComparison.OrdinalIgnoreCase)
                 || string.Equals(type, "FLOAT", StringComparison.OrdinalIgnoreCase)
                || (string.Equals(type, "NUMBER", StringComparison.OrdinalIgnoreCase) && isDecimal))
            {
                return "DBType.MySql_Decimal, Length = " + length;
            }
            else if (string.Equals(type, "date", StringComparison.OrdinalIgnoreCase)
                || string.Equals(type, "datetime", StringComparison.OrdinalIgnoreCase))
            {
                return "DBType.MySql_DateTime";
            }
            else if (string.Equals(type, "char", StringComparison.OrdinalIgnoreCase)
                ||string.Equals(type, "varchar", StringComparison.OrdinalIgnoreCase))
            {
                return "DBType.MySql_String, Length = " + length;
            }
            else if (string.Equals(type, "text", StringComparison.OrdinalIgnoreCase))
            {
                return "DBType.MySql_Text";
            }
            else if (string.Equals(type, "blob", StringComparison.OrdinalIgnoreCase))
            {
                return "DBType.MySql_Blob, Length = " + length;
            }
            return "DBType.MySql_String, Length = " + length;
        }
        /// <summary>
        /// 根据查询的数据类型转换成C#数据类型
        /// </summary>
        /// <param name="type">数据类型</param>
        /// <param name="decimalStr">是否是小数</param>
        /// <param name="length">length</param>
        /// <param name="canNullStr">能否为空</param>
        /// <returns></returns>
        public override string TransfromDbType2CCsharp(string type, string decimalStr, string length, string canNullStr)
        {
            bool isDecimal = !string.IsNullOrEmpty(decimalStr) && int.Parse(decimalStr) > 0;
            bool canNull = "Y".Equals(canNullStr, StringComparison.OrdinalIgnoreCase);
            if (string.IsNullOrEmpty(type))
            {
                return string.Empty;
            }

            if (string.Equals(type, "INTEGER", StringComparison.OrdinalIgnoreCase)
                || string.Equals(type, "int", StringComparison.OrdinalIgnoreCase)
                || (string.Equals(type, "NUMBER", StringComparison.OrdinalIgnoreCase) && !isDecimal))
            {
                return canNull ? "int?" : "int";
            }
            else if (string.Equals(type, "bigint", StringComparison.OrdinalIgnoreCase))
            {
                return canNull ? "Int64?" : "Int64";
            }
            else if (string.Equals(type, "DECIMAL", StringComparison.OrdinalIgnoreCase)
                || string.Equals(type, "FLOAT", StringComparison.OrdinalIgnoreCase)
                || (string.Equals(type, "NUMBER", StringComparison.OrdinalIgnoreCase) && isDecimal))
            {
                return canNull ? "decimal?" : "decimal";
            }
            else if (string.Equals(type, "date", StringComparison.OrdinalIgnoreCase))
            {
                return canNull ? "DateTime?" : "DateTime";
            }
            else if (string.Equals(type, "datetime", StringComparison.OrdinalIgnoreCase))
            {
                return canNull ? "DateTime?" : "DateTime";
            }
            else if (string.Equals(type, "char", StringComparison.OrdinalIgnoreCase)
                  || string.Equals(type, "varchar", StringComparison.OrdinalIgnoreCase))
            {
                return "string";
            }
            return "string";
        }
    }
}
